#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <iostream>
#include <pthread.h>
#include "lServer.h"

#define MAX_MSG 100

using namespace std;


Lserver::Lserver()
{
  cout << "Constructeur du programme Server" << endl;
}



void Lserver::demarrer(unsigned short int listenPort)
{
  int acceptSocket;
  socklen_t clientAddressLength;
  struct sockaddr_in clientAddress, serverAddress;

  // on cree la socket d'ecoute pour les connection des clients
  listenSocket = socket(AF_INET, SOCK_STREAM, 0);
  if (listenSocket < 0) {
    cerr << "cannot create listen socket";
    exit(1);
  }
  
  // repli la structure serverAddress
  serverAddress.sin_family = PF_INET;
  serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
  serverAddress.sin_port = htons(listenPort);
  
  if (bind(listenSocket,
           (struct sockaddr *) &serverAddress,
           sizeof(serverAddress)) < 0) {
    cerr << "cannot bind socket";
    exit(1);
  }
  
  // mise en ecoute du serveur
  listen(this->listenSocket, 5);
  
  cout << "Waiting for request on port " << listenPort << "\n";

  clientAddressLength = sizeof(clientAddress);
 

 
  while (1) {
    
    acceptSocket = accept(this->listenSocket, 
			  (struct sockaddr*)&clientAddress, 
			  &clientAddressLength);
    if (acceptSocket < 0){
      cout << "pb dans accept" << endl;
    }
    
    // show the client's IP address
    cout << "  from " << inet_ntoa(clientAddress.sin_addr);
    
    // Show the client's port number.
    cout << ":" << ntohs(clientAddress.sin_port) << "\n";
    
    pthread_t tid;
    pthread_create(&tid, NULL, handleClient, (void *) acceptSocket);
    
  }
}


Lserver::~Lserver()
{
}


void *handleClient(void *voidAcceptSocket)
{
  int acceptSocket = (int) voidAcceptSocket;
  int i, received = -1;
  char line[(MAX_MSG+1)];

  memset(line, 0x0, (MAX_MSG+1));
  if ((received = recv(acceptSocket, line, MAX_MSG, 0)) < 0) {
    cout << "  I/O Problem" << endl;
    exit(1);
  }
  cout << "  Received: " << line << "\n";
  
  while (received > 0){
  
    for (i = 0; line[i] != '\0'; i++)
      line[i] = toupper(line[i]);
    
    if (send(acceptSocket, line, strlen(line) + 1, 0) < 0)
      cerr << "Error: cannot send modified data" << endl;
    memset(line, 0x0, (MAX_MSG+1));  // set line to all zeroes
    
    if ((received = recv(acceptSocket, line, MAX_MSG, 0)) < 0) {
      cout << "  I/O Problem" << endl;
    }
    cout << "  Received: " << line << "\n";
    
  }

  close(acceptSocket);
}
